from django.shortcuts import render
from django_redis import get_redis_connection
from django.http import HttpResponse
from rest_framework.response import Response
from meiduo_mall.libs.captcha.captcha import captcha
from rest_framework.generics import GenericAPIView
import random
from rest_framework.views import APIView

# from meiduo_mall.libs.yuntongxun.sms import CCP
from . import constants
from .serializers import ImageCodeCheckSerializer

# from celery_tasks.sms.tasks import send_sms_code
from celery_tasks.sms import tasks

# Create your views here.

# 创建应用verifications
# meiduo_mall_Django/meiduo_mall/meiduo_mall/apps$ python ../../manage.py startapp verifications


class ImageCodeView(APIView):
    """图片验证码"""
    def get(self, request, image_code_id):
        """获取图片验证码"""

        # 生成验证码图片
        text, image = captcha.generate_captcha()

        # 获取到redis的连接对象
        # 在参数中传递配置名称，指明图片验证码的保存位置
        conn = get_redis_connection('verify_codes')

        # 通过redis连接对象可以执行redis命令
        # 保存到redis缓存中
        conn.setex('image_%s' % image_code_id, constants.IMAGE_CODE_REDIS_EXPIRES, text)

        # 固定返回验证码图片数据，不需要REST framework框架的Response帮助我们决定返回响应数据的格式
        # 所以此处直接使用Django原生的HttpResponse即可
        return HttpResponse(image, content_type='image/jpg')


# 继承GenericAPIView，是因为要使用序列化器验证图片验证码
class SMSCodeView(GenericAPIView):
    """短信验证码"""
    # 指明序列化器对象
    serializer_class = ImageCodeCheckSerializer

    def get(self, request, mobile):
        """获取短信验证码"""

        # 验证图片验证码
        # 检查60秒内是否有发送记录
        # 反序列化，调用序列化器校验，上面已指明序列化器类
        ser = self.get_serializer(data=request.query_params)
        ser.is_valid(raise_exception=True)

        # 生成短信验证码
        sms_code = random.randint(0, 999999)
        sms_code = "%06d" % sms_code

        # 指明短信验证码的保存位置
        conn = get_redis_connection('verify_codes')

        # 保存短信验证码与发送记录，在参数里面设置过期时间和频率（发送间隔）,参数 1 ，表示已经发送过了，在规定时间里不让再发送了
        # conn.setex('sms_%s' % mobile, constants.SMS_CODE_EXPIRE, sms_code)
        # conn.setex('send_flag_%s' % mobile, constants.SMS_CODE_RATE, 1)

        # 保存短信验证码，管道：优化redis操作，减少redis压力
        pl = conn.pipeline()

        # 有效期
        pl.setex('sms_%s' % mobile, constants.SMS_CODE_EXPIRE, sms_code)

        # 发送间隔，即多长时间记录一次
        pl.setex('send_flag_%s' % mobile, constants.SMS_CODE_RATE, 1)
        pl.execute()

        # 发送短信
        # ccp = CCP()
        # ccp.send_template_sms(mobile, sms_code, constants.SMS_CODE_TEMPLATE)

        # 使用celery异步任务发送短信
        sms_code_expires = str(constants.SMS_CODE_EXPIRE // 60)
        # send_sms_code.delay(mobile, sms_code, expire)
        tasks.send_sms_code.delay(mobile, sms_code, sms_code_expires)

        return Response({'message': 'ok'})
